# Copyright (C) 2015-2024, Wazuh Inc.
# Created by Wazuh, Inc. <info@wazuh.com>.
# This program is free software; you can redistribute it and/or modify it under the terms of GPLv2

from wazuh_testing.constants.paths.logs import WAZUH_LOG_PATH, ALERTS_JSON_PATH
from wazuh_testing.modules.modulesd.vulnerability_detector import patterns as cb
from wazuh_testing.tools.monitors.file_monitor import FileMonitor
from wazuh_testing.utils.callbacks import generate_callback


def check_event(pattern: str, replacement: str = None, file_monitor=None, timeout: int = 10) -> str:
    """Check if an event is detected in the monitored file.

    Args:
        pattern (str): regex used to match in file
        replacement (dict): Dictionary with replacements for regex
        file_monitor (FileMonitor): FileMonitor object with file to monitor set.
        timeout (int): timeout for file_monitor to check for events.
    """
    log_monitor = file_monitor if file_monitor is not None else FileMonitor(WAZUH_LOG_PATH)

    callback = generate_callback(regex=pattern, replacement=replacement)
    log_monitor.start(timeout=timeout, callback=callback)

    return log_monitor.callback_result


def check_cve_affects_package_log(agent_id, package, cve, timeout=10, log_monitor=None):
    """Check if inserted vulnerable packages are reported by vulnerability detector.

    Args:
        package (str): Name of custom package to check. Example: 'firefox-0'
        cve (str): Package CVE. Example: 'CVE-2019-11764'
        agent_id (str): Agent ID.
        timeout (int): timeout for file_monitor to check for events.
        log_monitor (FileMonitor): FileMonitor object with file to monitor set.
    """
    replacement = {"agent_id": agent_id, "package": package, "cve": cve}
    return check_event(pattern=cb.CVE_AFFECTS_PACKAGE, replacement=replacement, file_monitor=log_monitor,
                       timeout=timeout)


def check_cve_affects_package_alert(agent_id, package, cve, timeout=10):
    """Check if inserted vulnerable packages are reported by vulnerability detector.

    Args:
        package (str): Name of custom package to check. Example: 'firefox-0'
        cve (str): Package CVE. Example: 'CVE-2019-11764'
        agent_id (str): Agent ID.
        timeout (int): timeout for file_monitor to check for events.
    """
    log_monitor = FileMonitor(ALERTS_JSON_PATH)
    replacement = {"agent_id": agent_id, "package": package, "cve": cve}
    return check_event(pattern=cb.CVE_AFFECTS_AGENT_ALERT, replacement=replacement, file_monitor=log_monitor,
                       timeout=timeout)


def check_package_vulnerability_solved(package: str, cve: str, timeout: int = 10, log_monitor=None) -> str:
    """Check if vulnerability detector reports when a package vulnerability is solved.

    Args:
        package (str): Name of custom package to check. Example: 'firefox-0'
        cve (str): Package CVE. Example: 'CVE-2019-11764'
        timeout (int): timeout for file_monitor to check for events.
        log_monitor (FileMonitor): FileMonitor object with file to monitor set.
    """
    replacement = {"package": package, "cve": cve}
    return check_event(pattern=cb.CVE_AFFECTING_PACKAGE_SOLVED, replacement=replacement, file_monitor=log_monitor,
                       timeout=timeout)


def check_baseline_scan_start(agent_id, timeout=10, log_monitor=None):
    """Check if Baseline scan has started.

    Args:
        agent_id (str): Agent ID.
        timeout (int): timeout for file_monitor to check for events.
        log_monitor (FileMonitor): FileMonitor object with file to monitor set.
    """
    return check_event(pattern=cb.BASELINE_SCAN_START, replacement={"agent_id": agent_id},
                       file_monitor=log_monitor, timeout=timeout)


def check_full_scan_start(agent_id, timeout=10, log_monitor=None):
    """Check if Full scan has started.

    Args:
        agent_id (str): Agent ID.
        timeout (int): timeout for file_monitor to check for events.
        log_monitor (FileMonitor): FileMonitor object with file to monitor set.
    """
    return check_event(pattern=cb.FULL_SCAN_START, replacement={"agent_id": agent_id},
                       file_monitor=log_monitor, timeout=timeout)


def check_partial_scan_start(agent_id, timeout=10, log_monitor=None):
    """Check if Partial scan has started.

    Args:
        agent_id (str): Agent ID.
        timeout (int): timeout for file_monitor to check for events.
        log_monitor (FileMonitor): FileMonitor object with file to monitor set.
    """
    return check_event(pattern=cb.PARTIAL_SCAN_START, replacement={"agent_id": agent_id},
                       file_monitor=log_monitor, timeout=timeout)


def check_vuln_assesment_finished(agent_id, timeout=10, log_monitor=None):
    """Check if vulnerability assesment has finished.

    Args:
        agent_id (str): Agent ID.
        timeout (int): timeout for file_monitor to check for events.
        log_monitor (FileMonitor): FileMonitor object with file to monitor set.
    """
    return check_event(pattern=cb.FINISHED_VUNERABILITY_ASSESMENT, replacement={"agent_id": agent_id},
                       file_monitor=log_monitor, timeout=timeout)
